#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <sys/poll.h>

#define MAXNUM 1024

int clientFd[1024];
int serverFd;
int r=0;

void hand(int s)
{
    if (2==s)
    {
        //close 断开链接
        printf("bye bye\n");
        for (int i=0;i<MAXNUM;i++)
        {
            if (clientFd[i]!=-1)
            {
                close(clientFd[i]);
            }
        }

        close(serverFd);
        exit(1);
    }
}


void init()
{
    for (int i=0;i<MAXNUM;i++)
    {
        clientFd[i]=-1;
    }

    //创建socket
    serverFd = socket(AF_INET,SOCK_STREAM,0);
    if (-1==serverFd)
    {
        printf("创建socket失败\n");
        exit(-1);
    }
    printf("创建socket成功\n");

    //协议地址簇
    struct sockaddr_in addr={0};
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr=inet_addr("127.0.0.1");//ip地址 注意字符串转网络字节序
    addr.sin_port=htons(4556);


    //绑定
    r = bind(serverFd,( struct sockaddr*)&addr,sizeof addr);

    if (-1==r)
    {
        printf("绑定失败:%m\n");
        close(serverFd);
        exit(-1);
    }
    printf("绑定成功\n");

    //监听
    r = listen(serverFd,100);
    if (-1==r)
    {
        printf("监听失败:%m\n");
        close(serverFd);
        exit(-1);
    }
    printf("监听成功\n");

    //接受客户端连接
    //
    // struct sockaddr_in cAddr = {0}; //用来接受客户端的协议地址簇
    // int len = sizeof cAddr;
}

void *handle_client(void *arg)
{
    char buff[1024];
    char temp[1024];
    int n=0;
    int* client  =(int*) arg;
    char temp[1024];
    while (1)
    {
        int r = recv(*client,buff,1023,0);
        if (r>0)
        {
            buff[r] = 0; //添加字符串结束符号
            printf("%d:%s\n",r,buff);

            //转发
            memset(temp,0,1024); //先清空
            sprintf(temp,"%d>>%s",*client,buff);

            for (int i=0;i<MAXNUM;i++)
            {
                if (-1!=clientFd[i])
                {
                    if (*client!=clientFd[i])
                    {
                        send(clientFd[i],temp,strlen(temp),0);
                    }
                }
            }

        }
    }
}


int main(){


    signal(2,hand);
    init();

    //接收客户端连接
    // fd_set fds;
    struct  pollfd fds[MAXNUM];
    int currNum =0; //当前描述数量
    fds[0].fd = serverFd;
    fds[0].events=POLLIN;
    currNum++;
    char buff[1024];
    while (1)
    {
        r = poll(fds,currNum,0);
        if (-1==r)
        {
            printf("poll 出bug了：%m\n");
            exit(-1);
        }else if (0==r)
        {
            continue;
        }else
        {
            if (fds[0].revents&POLLIN) //是否有客户端连接
            {
                int cfd = accept(serverFd,NULL,NULL);
                if (-1==cfd)
                {
                    printf("客户端连接失败:%m\n");
                }else
                {
                    printf("有客户端连接上服务器了%d\n",cfd);
                    for (int i=0;i<MAXNUM;i++)
                    {
                        if (-1==clientFd[i])
                        {
                            clientFd[i]=cfd;
                            fds[currNum].fd = cfd;
                            fds[currNum].events=POLLIN;
                            currNum++;
                            break;
                        }
                    }
                    printf("currNum:%d\n",currNum);

                }

            }

            //判断客户端的描述符号是否有动静
            for (int i=1;i<MAXNUM;i++)
            {
                if (-1!=clientFd[i-1] && (fds[i].revents&POLLIN))
                {
                    int len = recv(fds[i].fd,buff,1023,0);
                    if (len >0)
                    {
                        buff[len]=0;
                        printf("%d:%s\n",fds[i].fd,buff);
                    }else
                    {
                        printf("%d断开链接了\n",fds[i].fd);
                    }
                }
            }

        }


    }
}
